<script
	lang="ts"
	setup
	generic="
		T extends {
			[key: string]: any;
		}
	"
>
import { ElementColumsType } from "#/element-plus";
import { FormInstance, FormRules } from "element-plus";
import { ref } from "vue";

const props = withDefaults(
	defineProps<{
		form: T;
		formColums: ElementColumsType<T>[];
		rules?: FormRules<Required<T>>;
	}>(),
	{},
);

const form = defineModel<T>("form");
const ruleFormRef = ref<FormInstance>();

// 提交
const submitForm = async (formEl: FormInstance | undefined) => {
	if (!formEl) return;
	await formEl.validate((valid, fields) => {
		console.log("valid, fields =>   ", valid, fields);
		if (valid) {
			console.log("submit!");
		} else {
			console.log("error submit!", fields);
		}
	});
};

// 重置
const resetForm = (formEl: FormInstance | undefined) => {
	if (!formEl) return;
	formEl.resetFields();
};
</script>

<template>
	<!-- props.formColums.some((item) => item.label)  不存在label说明是筛选框模式 -->
	<el-form
		ref="ruleFormRef"
		:model="form"
		label-width="auto"
		:rules="props?.rules"
		:class="props.formColums.some((item) => item.label) ? '' : 'inline-flex gap-10'"
	>
		<template v-for="item in props.formColums" :key="JSON.stringify(item)">
			<!-- input输入框 -->
			<el-form-item :label="item.label" :prop="item.prop">
				<a-tooltip :effect="item.tooltip?.effect || 'dark'" :placement="item.tooltip?.placement || 'top'">
					<template #content v-if="item.tooltip?.content">
						<span> {{ item.tooltip?.content }} </span>
					</template>
					<el-input
						v-if="item.type === 'input' && item.prop && form?.hasOwnProperty(item.prop)"
						v-model="form[item.prop]"
						:type="item.payload?.type"
						:class="item.payload?.className"
						:size="item.payload?.size"
						:placeholder="item.payload?.placeholder"
						:clearable="item.payload?.clearable"
					/>
					<!-- select选择器 -->
					<el-select
						v-if="item.type === 'select' && item.prop && form?.hasOwnProperty(item.prop)"
						v-model="form[item.prop]"
						:class="item.payload?.className"
						:size="item.payload?.size"
						:placeholder="item.payload?.placeholder"
						:clearable="item.payload?.clearable"
						:multiple="item.payload?.multiple"
						:collapse-tags="item.payload?.collapseTags ? true : item.payload?.collapseTags"
						:collapse-tags-tooltip="
							item.payload?.collapseTagsTooltip ? true : item.payload?.collapseTagsTooltip
						"
						:max-collapse-tags="item.payload?.maxCollapseTags || 1"
					>
						<template
							#header
							v-if="
								item.payload?.multiple &&
								item.payload?.options?.length &&
								item.payload?.options?.length > 0
							"
						>
							<el-button
								text
								bg
								@click="
									() => {
										if (item.prop && form && Array.isArray(form[item.prop])) {
											// 判断当前是否已经是全选
											if (form[item.prop].length === item.payload?.options?.length) {
												(form[item.prop] as string[]) = [];
											} else {
												(form[item.prop] as string[]) = item.payload!.options!.map(
													(_) => _.value,
												);
											}
										}
									}
								"
							>
								<el-text truncated>全选/全不选</el-text>
							</el-button>
						</template>
						<el-option
							v-for="(option, index) in item.payload?.options"
							:key="option?.id || index"
							:label="option.label"
							:value="option.value"
						/>
					</el-select>
					<!-- select虚拟化选择器 -->
					<el-select-v2
						v-if="item.type === 'select-v2' && item.prop && form?.hasOwnProperty(item.prop)"
						v-model="form[item.prop]"
						:class="item.payload?.className"
						:size="item.payload?.size"
						:placeholder="item.payload?.placeholder"
						:clearable="item.payload?.clearable"
						:options="item.payload?.options"
					/>
					<!-- switch开关 -->
					<el-switch
						v-if="item.type === 'switch' && item.prop && form?.hasOwnProperty(item.prop)"
						v-model="form[item.prop]"
						:class="item.payload?.className"
						:size="item.payload?.size"
						style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949"
					/>
					<!-- Segmented 分段控制器 -->
					<el-segmented
						v-if="item.type === 'segmented' && item.prop && form?.hasOwnProperty(item.prop)"
						v-model="form[item.prop]"
						:class="item.payload?.className"
						:size="item.payload?.size"
						:options="item.payload?.options"
					>
						<template #default="{ item }">
							<div class="flex flex-col items-center gap-2 p-2">
								<el-icon size="20">
									<component :is="item.icon" />
								</el-icon>
								<div>{{ item.label }}</div>
							</div>
						</template>
					</el-segmented>
					<!-- checkbox 多选框 -->
					<el-checkbox-group
						v-if="item.type === 'checkbox' && item.prop && form?.hasOwnProperty(item.prop)"
						v-model="form[item.prop]"
					>
						<el-checkbox
							v-for="(option, index) in item.payload?.options"
							:key="option?.id || index"
							:value="option.value"
						>
							{{ option.label }}
						</el-checkbox>
					</el-checkbox-group>
					<!-- radio 单选框 -->
					<el-radio-group
						v-if="item.type === 'radio' && item.prop && form?.hasOwnProperty(item.prop)"
						v-model="form[item.prop]"
					>
						<el-radio
							v-for="(option, index) in item.payload?.options"
							:key="option?.id || index"
							:value="option.value"
						>
							{{ option.label }}
						</el-radio>
					</el-radio-group>
					<!-- 提交 -->
					<div v-if="item.type === 'button'" class="center-x w-100%">
						<el-button
							v-if="item.payload?.list?.includes('submit')"
							type="primary"
							@click="submitForm(ruleFormRef)"
						>
							提交
						</el-button>
						<el-button v-if="item.payload?.list?.includes('reset')" @click="resetForm(ruleFormRef)">
							重置
						</el-button>
					</div>
				</a-tooltip>
			</el-form-item>
		</template>
	</el-form>
</template>
